/**
 * 
 */
package com.baihui.taobao.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.quartz.CronExpression;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;

import com.baihui.taobao.db.DBConnectionMgr;
import com.baihui.taobao.quartz.jobs.BuyerImportJob;
import com.baihui.taobao.quartz.jobs.InvImportJob;
import com.baihui.taobao.quartz.jobs.OrderImportJob;
import com.baihui.taobao.quartz.jobs.ProductImportJob;
import com.baihui.taobao.util.Util;

/**
 * @author dev 任務導入調度執行
 */
public class TaskScheduleServlet extends HttpServlet {

	/**
	 * 服務器啟動時則執行后臺導入調度
	 * 
	 * @see javax.servlet.GenericServlet#init()
	 */
	@Override
	public void init() throws ServletException {
		try {
//			DBConnectionMgr.getInstance().init(
//					this.getServletContext().getRealPath(
//							this.getInitParameter("Dbconfig")));
			this.scheduler();
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}

	/**
	 * 根據用戶執行對應的任務
	 * 
	 * @param userID
	 * @param jobClass
	 * @param schedulerExp
	 * @throws SchedulerException
	 */
	protected void startTask(String userID, String userNick, int jobID,
			Class jobClass, String schedulerExp, String jobdesc)
			throws SchedulerException {
		System.out.println(userNick + ":" + jobdesc + " starting....");

		try {
			Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

			long ctime = System.currentTimeMillis();

			String jobDetailName = userID + "_" + jobClass.getName()
					+ "_jobDetail";

			JobDetail jobDetail = new JobDetail(jobDetailName,
					"jobDetailGroup", jobClass);
			String secret = this.getInitParameter("APPKEY")
					+ this.getInitParameter("APPSecretVALUE");
			String sign = Util.md5Signature(secret);
			jobDetail.getJobDataMap().put("sign", sign);
			jobDetail.getJobDataMap().put(
					"contextPath",
					"http://localhost"
							+ this.getServletContext().getContextPath());
			jobDetail.getJobDataMap().put("userID", userID);

			String triggerName = userID + "_" + jobID + "_trigger";
			CronTrigger cronTrigger = new CronTrigger(triggerName,
					"triggerGroup");

//			CronExpression cexp = new CronExpression(schedulerExp);
//			cronTrigger.setCronExpression(cexp);

			SimpleTrigger trigger= new SimpleTrigger(triggerName, "triggerGroup",SimpleTrigger.REPEAT_INDEFINITELY , 1000 * Long.parseLong(schedulerExp) * 60);
			
			scheduler.scheduleJob(jobDetail, trigger);
			scheduler.start();

			// 更新最近一次抽取时间
		} catch (Exception e) {
			System.out.println(userNick + ":" + jobdesc + " 异常终止，原因如下:");
			e.printStackTrace();
		}
	}

	/**
	 * 開始調度
	 */
	protected void scheduler() {
		// 獲取所有關聯用戶記錄
		Connection cn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			cn = DBConnectionMgr.getConnection();
			cn.setAutoCommit(false);
			// 取得目前导入交易的最大时间，将哪个时间作为开始时间
			String sql = "select ts.baihuiuser,ts.nick,tt.*,tj.* from topsession ts,ttriggle tt,tjob tj where ts.baihuiuser=tt.userid and tt.jobid=tj.jobid";
			ps = cn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				String userID = rs.getString("userid");
				String userNick = rs.getString("nick");
				int jobType = rs.getInt("jobid");
				String triggleExp = rs.getString("cronExp");
				String jobDesc = rs.getString("jobdescription");

				Class jobClass = null;
				switch (jobType) {
				case 1:
					jobClass = ProductImportJob.class;
					break;
				case 2:
					jobClass = OrderImportJob.class;
					break;
				case 3:
					jobClass = BuyerImportJob.class;
					break;
				case 4:
					jobClass = InvImportJob.class;
				}

				// 開始執行任務
				updateLastImportDate(userID, jobType,
						new Timestamp(System.currentTimeMillis()));

				// 开始任务执行
				startTask(userID, userNick, jobType, jobClass, triggleExp,
						jobDesc);
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		} finally {
			releaseDBConnection(cn, ps, rs);
		}
	}

	/**
	 * 重新针对触发器进行调度
	 */
	private void reschduleJob(HttpServletRequest req, HttpServletResponse resp)
			throws Exception {
		String userID = req.getParameter("userID");
		String jobID = req.getParameter("jobID");
		String cronExp = req.getParameter("time");

		String triggerName = userID + "_" + jobID + "_trigger";
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		// CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerName,
		//
		SimpleTrigger trigger= new SimpleTrigger(triggerName, "triggerGroup",SimpleTrigger.REPEAT_INDEFINITELY,100000000);
		
		scheduler.rescheduleJob(triggerName, "triggerGroup", trigger);
	}

	/*
	 * 更新最新抽取时间
	 */
	private void updateLastImportDate(String userID, long jobID,
			Timestamp lastImportDate) {
		// 獲取所有關聯用戶記錄
		Connection cn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			cn = DBConnectionMgr.getConnection();
			cn.setAutoCommit(true);
			// 取得目前导入交易的最大时间，将哪个时间作为开始时间
			String sql = "update ttriggle set lastimpdate=? where userid=? and jobid=?";
			ps = cn.prepareStatement(sql);
			ps.setTimestamp(1, lastImportDate);
			ps.setString(2, userID);
			ps.setLong(3, jobID);
			ps.execute();
		} catch (Exception exception) {
			exception.printStackTrace();
		} finally {
			releaseDBConnection(cn, ps, rs);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
	 * , javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		updateScheduleTime(req, resp);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest
	 * , javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		updateScheduleTime(req, resp);
	}

	private void updateScheduleTime(HttpServletRequest req,
			HttpServletResponse resp) {
		String userID = req.getParameter("userID");
		String jobID = req.getParameter("jobID");
		String scheduleTime = req.getParameter("scheduleTime");

		Connection cn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			cn = DBConnectionMgr.getConnection();
			cn.setAutoCommit(true);
			// 取得目前导入交易的最大时间，将哪个时间作为开始时间
			String sql = "update ttriggle set cronExp=? where userid=? and jobid=?";
			ps = cn.prepareStatement(sql);
			ps.setString(1, scheduleTime);
			ps.setLong(2, Long.parseLong(userID));
			ps.setLong(3, Long.parseLong(jobID));
			ps.execute();
		} catch (Exception exception) {
			exception.printStackTrace();
		} finally {
			releaseDBConnection(cn, ps, rs);
		}
	}

	/*
	 * 關閉數據庫連接
	 */
	private void releaseDBConnection(Connection cn, PreparedStatement ps,
			ResultSet rs) {
		try {
			if (rs != null)
				rs.close();
			if (ps != null)
				ps.close();
			if (cn != null)
				cn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
